/*
 * main.cpp
 *
 *  Created on: 06/04/2012
 *      Author: lucas
 */

#include <iostream>
#include <stdio.h>
#include "../hdr/EmisorAritmetico.h"
#include "../hdr/LectorAritmetico.h"

#define MAX_TOTAL_LARGOS 16384

using namespace std;

int renormalizarFrecuencias(unsigned short* frecuencias, int cantidad) {
	int total = 0;
	for (int i = 0; i < cantidad; i++) {
		frecuencias[i] = frecuencias[i] / 2 + 1;
		total += frecuencias[i];
	}
	return total;
}

int main() {
	// Parte de compresión
	FILE* input = fopen("ww.txt", "rb");
	FILE* comprimido = fopen("comprimido.ppm", "wb");
	EmisorAritmetico emisor(comprimido);

	unsigned char c;
	unsigned short largos[257];
	int total = 0;
	for (int i = 0; i < 257; i++) {
		total++;
		largos[i] = 1;
	}
	int i = 0;
	while (fread(&c, sizeof(char), 1, input) == 1) {
		int piso = 0;
		int j;
		if(i % (1024 * 1024) == 0)
			fprintf(stdout, "%d MB\n", i / 1024 / 1024);
		for (j = 0; j < c; j++) {
			piso += largos[j];
		}
		emisor.emitirSimbolo(piso, largos[j], total);
		largos[j]++;
		total++;
		i++;
		if(total >= MAX_TOTAL_LARGOS)
			total = renormalizarFrecuencias(largos, 257);
	}
	emisor.emitirSimbolo(total - largos[256], largos[256], total); // EOF
	emisor.finalizarEmision();
	fclose(input);
	fclose(comprimido);
	cout << endl;

	// Parte de descompresión
	unsigned int caracter;
	comprimido = fopen("comprimido.ppm", "rb");
	FILE* output = fopen("output.txt", "wb");
	LectorAritmetico lector(comprimido);
	total = 0;
	for (int i = 0; i < 257; i++) {
		total++;
		largos[i] = 1;
	}
	i = 0;
	while ((caracter = lector.leerSimbolo(largos, total, 257)) != 256) {
		c = (char) caracter;
		if(i % (1024 * 1024) == 0)
			fprintf(stdout, "%d MB\n", i / 1024 / 1024);
		i++;
//		if(i >= 10000) break;
		fwrite(&c, sizeof(char), 1, output);
		largos[(int)c]++;
		total++;
		if(total >= MAX_TOTAL_LARGOS)
			total = renormalizarFrecuencias(largos, 257);
	}
	fclose(comprimido);
	fclose(output);
	return 0;
}
